home *** CD-ROM | disk | FTP | other *** search
- /* +-------------------------------------------------------------------+ */
- /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
- /* | | */
- /* | Permission to use, copy, modify, and to distribute this software | */
- /* | and its documentation for any purpose is hereby granted without | */
- /* | fee, provided that the above copyright notice appear in all | */
- /* | copies and that both that copyright notice and this permission | */
- /* | notice appear in supporting documentation. There is no | */
- /* | representations about the suitability of this software for | */
- /* | any purpose. this software is provided "as is" without express | */
- /* | or implied warranty. | */
- /* | | */
- /* +-------------------------------------------------------------------+ */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <math.h>
- #include "xpaint.h"
- #include "misc.h"
- #include "Paint.h"
-
- #define FILL 0x02
- #define CIRCLE 0x01
- #define ISFILL(x) ((x) & FILL)
- #define ISCIRCLE(x) ((x) & CIRCLE)
-
- typedef struct {
- Boolean typeFlag, swap;
- int rx, ry, startX, startY, endX, endY, drawn, flag;
- GC gcx;
- } LocalInfo;
-
- static int radiusMode = False;
-
- static XRectangle *draw(Widget w, Drawable d, GC lgc, GC fgc, LocalInfo *l)
- {
- static XRectangle rect;
- XArc arc;
- int sx = l->startX, sy = l->startY;
- int ex = l->endX, ey = l->endY;
-
- if (l->startX == l->endX && l->startY == l->endY)
- return NULL;
-
- arc.x = MIN(sx, ex);
- arc.y = MIN(sy, ey);
- arc.width = MAX(sx, ex) - arc.x;
- arc.height = MAX(sy, ey) - arc.y;
-
- if (radiusMode) {
- int r2 = arc.width * arc.width + arc.height * arc.height;
- int r;
-
- r = sqrt((double)r2);
- arc.x = l->startX - r;
- arc.y = l->startY - r;
- arc.width = r * 2;
- arc.height = r * 2;
- } else {
- if (ISCIRCLE(l->typeFlag))
- arc.height = arc.width = MAX(arc.width, arc.height);
- if (arc.x != sx)
- arc.x = sx - arc.width;
- if (arc.y != sy)
- arc.y = sy - arc.height;
- }
- arc.angle1 = 0;
- arc.angle2 = 360*64;
-
- if (fgc != None)
- XFillArcs(XtDisplay(w), d, fgc, &arc, 1);
- if (lgc != None)
- XDrawArcs(XtDisplay(w), d, lgc, &arc, 1);
-
- rect.x = arc.x;
- rect.y = arc.y;
- rect.width = arc.width + 1;
- rect.height = arc.height + 1;
-
- return ▭
- }
-
- static void press(Widget w, LocalInfo *l,
- XButtonEvent *event, OpInfo *info)
- {
- /*
- ** Check to make sure all buttons are up, before doing this
- */
- if ((event->state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
- return;
-
- l->rx = info->x;
- l->ry = info->y;
- l->endX = l->startX = event->x;
- l->endY = l->startY = event->y;
-
- l->swap = (event->button == Button2);
-
- l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
-
- l->drawn = False;
- }
-
- static void motion(Widget w, LocalInfo *l,
- XMotionEvent *event, OpInfo *info)
- {
- if (l->drawn)
- draw(w, info->drawable, l->gcx, None, l);
-
- l->endX = event->x;
- l->endY = event->y;
-
- /*
- ** Really set this flag in the if statement
- */
- l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
- l->drawn = (draw(w, info->drawable, l->gcx, None, l) != NULL);
- }
-
- static void release(Widget w, LocalInfo *l,
- XButtonEvent *event, OpInfo *info)
- {
- XRectangle *undo;
- int mask;
- GC fgc, lgc;
-
- /*
- ** Check to make sure all buttons are up, before doing this
- */
- mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
- switch (event->button) {
- case Button1: mask ^= Button1Mask; break;
- case Button2: mask ^= Button2Mask; break;
- case Button3: mask ^= Button3Mask; break;
- case Button4: mask ^= Button4Mask; break;
- case Button5: mask ^= Button5Mask; break;
- }
- if ((event->state & mask) != 0)
- return;
-
- if (l->drawn && info->surface == opWindow)
- draw(w, info->drawable, l->gcx, None, l);
-
- if (info->surface == opWindow && info->isFat)
- return;
-
- UndoStart(w, info);
-
- l->startX = l->rx;
- l->startY = l->ry;
- l->endX = event->x;
- l->endY = event->y;
-
- if (l->swap) {
- fgc = info->first_gc;
- lgc = info->second_gc;
- } else {
- fgc = info->second_gc;
- lgc = info->first_gc;
- }
-
- if (!ISFILL(l->flag))
- fgc = None;
-
- undo = draw(w, info->drawable, lgc, fgc, l);
-
- if (info->surface == opPixmap && undo != NULL) {
- UndoSetRectangle(w, undo);
- PwUpdate(w, undo, False);
- }
- }
-
- /*
- ** Those public functions
- */
- void *CircleAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
- l->flag = CIRCLE;
- l->gcx = GetGCX(w);
- XtVaSetValues(w, XtNcompress, True, NULL);
- OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
- return l;
- }
- void CircleRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- XtFree((XtPointer)l);
- }
- void *FCircleAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
- l->flag = CIRCLE|FILL;
- l->gcx = GetGCX(w);
- XtVaSetValues(w, XtNcompress, True, NULL);
- OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
- return l;
- }
- void FCircleRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- XtFree((XtPointer)l);
- }
- void *OvalAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
- l->flag = 0;
- l->gcx = GetGCX(w);
- XtVaSetValues(w, XtNcompress, True, NULL);
- OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
- return l;
- }
- void OvalRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- XtFree((XtPointer)l);
- }
- void *FOvalAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
- l->flag = FILL;
- l->gcx = GetGCX(w);
- XtVaSetValues(w, XtNcompress, True, NULL);
-
- OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
- return l;
- }
- void FOvalRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- XtFree((XtPointer)l);
- }
-
- void CircleSetStyle(Boolean value)
- {
- radiusMode = value;
- }
- Boolean CircleGetStyle()
- {
- return radiusMode;
- }
-